package cn.iocoder.yudao.module.resource.service.message.impl;

import cn.hutool.crypto.digest.DigestUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.infra.util.TraceIdUtil;
import cn.iocoder.yudao.module.resource.api.enums.EnumAipError;
import cn.iocoder.yudao.module.resource.api.enums.MessageContentTypeEnum;
import cn.iocoder.yudao.module.resource.api.enums.MessageSourceTypeEnum;
import cn.iocoder.yudao.module.resource.controller.admin.message.vo.MessagePageReqVO;
import cn.iocoder.yudao.module.resource.dal.dataobject.message.MessageDO;
import cn.iocoder.yudao.module.resource.dal.mysql.message.MessageMapper;
import cn.iocoder.yudao.module.resource.dal.redis.ResourceLockRedisDAO;
import cn.iocoder.yudao.module.resource.service.message.MessageService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;

/**
 * 对话 Service 实现类
 *
 * @author lizhongwen
 */
@Slf4j
@Service
@Validated
public class MessageServiceImpl implements MessageService {

    @Resource
    private MessageMapper messageMapper;
    @Resource
    private ResourceLockRedisDAO resourceLockRedisDAO;

    @Override
    public void deleteMessageByUserId(Long userId) {
        final LambdaQueryWrapper<MessageDO> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(MessageDO::getUserId, userId);
        messageMapper.delete(wrapper);
    }

    @Override
    public MessageDO createMessage(String messageId,
                                   Long userId,
                                   MessageSourceTypeEnum senderType,
                                   MessageContentTypeEnum contentType,
                                   String gameMatchId,
                                   String wsSessionId,
                                   Integer roleId,
                                   String userText,
                                   String replyText,
                                   List<MessageDO.AudioData> audioDataList,
                                   Integer responseTimeMs) {
        // 插入
        final MessageDO message = new MessageDO();
        final String traceId = TraceIdUtil.getTraceId();
        message.setTraceId(traceId);
        message.setMessageId(messageId);
        message.setUserId(userId);
        message.setSenderType(senderType.getValue());
        message.setContentType(contentType.getValue());
        message.setResponseTimeMs(responseTimeMs);
        message.setGameMatchId(gameMatchId);
        message.setWsSessionId(wsSessionId);
        message.setRoleId(roleId);
        message.setUserText(userText);
        message.setUserTextHash(DigestUtil.md5Hex(userText));
        message.setReplyText(replyText);
        message.setReplyTextHash(DigestUtil.md5Hex(replyText));
        message.setAudioData(audioDataList);
        message.setCreateTime(LocalDateTime.now());
        message.setUpdateTime(LocalDateTime.now());
        messageMapper.insertOrUpdate(message);

        log.info("保存消息, messageId = {}, wsSessionId = {}", messageId, wsSessionId);
        return message;
    }

    @Override
    public int updateAudioDataById(String messageId, List<MessageDO.AudioData> audioDataList) {
        MessageDO message = new MessageDO();
        message.setMessageId(messageId);
        message.setAudioData(audioDataList);
        return messageMapper.updateById(message);
    }

    private void validateMessageExists(Long id) {
        if (messageMapper.selectById(id) == null) {
            throw exception(EnumAipError.MESSAGE_NOT_EXISTS);
        }
    }

    @Override
    public MessageDO getMessage(String id) {
        return messageMapper.selectById(id);
    }

    @Override
    public MessageDO getMessageByUserId(Long userId, String id) {
        return messageMapper.selectOne(MessageDO::getCreator, userId, MessageDO::getMessageId, id);
    }

    @Override
    public PageResult<MessageDO> getMessagePage(MessagePageReqVO pageReqVO) {
        return messageMapper.selectPage(pageReqVO);
    }

    @Override
    public PageResult<MessageDO> getMessagePageByUserId(Long userId, MessagePageReqVO pageReqVO) {
        return messageMapper.getMessagePageByUserId(userId, pageReqVO);
    }
}